import { Action } from 'redux';

type A = Action<string> & { payload?: any };

export type Reducer<T = any> = (state: T, action: A) => T;

export interface Reducers<T = any> {
  [key: string]: Reducer<T>;
}

export type Commit<T = any> = (type: string, payload?: T) => Promise<any>;

export type Effect<Payload = any, Res = any> = (payload: Payload, action: EffectAction) => Promise<Res>;


interface EffectAction {
  put: (opts: A) => any;
  call: (mapState: MapState<any>) => any;
  commit: Commit;
}

export interface Effects<Payload = any, Res = any> {
  [key: string]: Effect<Payload, Res>;
}

export interface ModelOptions<T = any> {
  namespace: string;
  state: T;
  effects?: Effects;
  reducers: Reducers<T>;
}

export type MapState<T> = (state: T) => any;

export type ConnectProps = {
  commit?: Commit
}

export type ModelOpts<T = any> = {
  default?:ModelOptions<T>
} | ModelOptions;
